//
//  ZYHttpManager.swift
//  ZYHttp
//
//  Created by Yi Zhou on 2025/1/14.
//

import Foundation
import Alamofire

public typealias ZYHttpSuccess = ((_ result: [String: Any]) ->Void)
public typealias ZYHttpFailure = ((_ error: Error) ->Void)

//MARK: - 网络请求库
public class ZYHttpManager: NSObject {
    
    private override init() {}
    
    public static let shared = ZYHttpManager()
    
    /// 常用配置信息
    public lazy var config: ZYHttpConfig = {
        return ZYHttpConfig()
    }()
    
    /// AFN风格的请求
    /// - Parameters:
    ///   - requestUrl: requestUrl description
    ///   - method: method description
    ///   - parameter: parameter description
    ///   - header: header description
    ///   - completion: completion description
    public func request(_ requestUrl: String,
                        _ method: HTTPMethod,
                        _ parameter: [String: Any]?,
                        _ header: [String: String]?,
                        _ success: ZYHttpSuccess?,
                        _ failure: ZYHttpFailure?) {
        
        /// 处理url
        guard let URL = URL(string: config.baseUrl + requestUrl) else {
            failure?(ZYHttpError.invalidURL(message: "生成URL失败"))
            return
        }
        
        /// 处理headers
        var headers = HTTPHeaders()
        let myHeaders = config.headers
        myHeaders.forEach { key, value in
            headers.add(name: key, value: value)
        }
        if let header = header {
            header.forEach { key, value in
                headers.add(name: key, value: value)
            }
        }
        
        /// 发起请求
        AF.request(URL, method: method, parameters: parameter, headers: headers).response { [weak self] dataResponse in
            switch dataResponse.result {
            case .success(let data):
                if let resData = data {
                    /// 转json
                    guard let json = String(data: resData, encoding: .utf8) else {
                        failure?(ZYHttpError.invalidResponse(message: "转json失败"))
                        debugPrint("***************ZYHttpManager failure***************")
                        return
                    }
                    /// 转字典
                    guard let infoDict = self?.jsonToDict(json) else {
                        failure?(ZYHttpError.invalidResponse(message: "转字典失败"))
                        debugPrint("***************ZYHttpManager failure***************")
                        return
                    }
                    /// 回调
                    success?(infoDict)
                    /// 打印日志
                    if self?.config.openLog == true {
                        debugPrint("***************ZYHttpManager success***************")
                        debugPrint(json)
                    }
                }
            case .failure(let error):
                failure?(error)
                debugPrint("***************ZYHttpManager failure***************")
            }
        }
        
        /// 打印日志
        if config.openLog {
            debugPrint("***************ZYHttpManager start***************")
            debugPrint("url：\(config.baseUrl + requestUrl)")
            debugPrint("method：\(method.rawValue)")
            debugPrint("headers：\(config.headers)")
            debugPrint("parameter：\(parameter ?? [:])")
            /// 尝试构建完整请求url，以下如果没有参数就不打印了
            var components = URLComponents(string: config.baseUrl + requestUrl)
            if let para: Parameters = parameter {
                components?.queryItems = para.map { key, value in
                    URLQueryItem(name: key, value: "\(value)")
                }
                if let fullURL = components?.url {
                    debugPrint("完整请求：\(fullURL)")
                }
            }
        }
    }
    
    /// 兼容某些场景需要自定义配置信息
    /// - Parameters:
    ///   - config: config description
    ///   - requestUrl: requestUrl description
    ///   - method: method description
    ///   - parameter: parameter description
    ///   - header: header description
    ///   - success: success description
    ///   - failure: failure description
    public func request(with config: ZYHttpConfig?,
                        _ requestUrl: String,
                        _ method: HTTPMethod,
                        _ parameter: [String: Any]?,
                        _ header: [String: String]?,
                        _ success: ZYHttpSuccess?,
                        _ failure: ZYHttpFailure?) {
        
        guard let useConfig = config else {
            request(requestUrl, method, parameter, header, success, failure)
            return
        }
        
        /// 处理url
        guard let URL = URL(string: useConfig.baseUrl + requestUrl) else {
            failure?(ZYHttpError.invalidURL(message: "生成URL失败"))
            return
        }
        
        /// 处理headers
        var headers = HTTPHeaders()
        let myHeaders = useConfig.headers
        myHeaders.forEach { key, value in
            headers.add(name: key, value: value)
        }
        if let header = header {
            header.forEach { key, value in
                headers.add(name: key, value: value)
            }
        }
        
        /// 发起请求
        AF.request(URL, method: method, parameters: parameter, headers: headers).response { [weak self] dataResponse in
            switch dataResponse.result {
            case .success(let data):
                if let resData = data {
                    /// 转json
                    guard let json = String(data: resData, encoding: .utf8) else {
                        failure?(ZYHttpError.invalidResponse(message: "转json失败"))
                        debugPrint("***************ZYHttpManager failure***************")
                        return
                    }
                    /// 转字典
                    guard let infoDict = self?.jsonToDict(json) else {
                        failure?(ZYHttpError.invalidResponse(message: "转字典失败"))
                        debugPrint("***************ZYHttpManager failure***************")
                        return
                    }
                    /// 回调
                    success?(infoDict)
                    /// 打印日志
                    if useConfig.openLog == true {
                        debugPrint("***************ZYHttpManager success***************")
                        debugPrint(json)
                    }
                }
            case .failure(let error):
                failure?(error)
                debugPrint("***************ZYHttpManager failure***************")
            }
        }
        
        /// 打印日志
        if useConfig.openLog {
            debugPrint("***************ZYHttpManager start***************")
            debugPrint("url：\(useConfig.baseUrl + requestUrl)")
            debugPrint("method：\(method.rawValue)")
            debugPrint("headers：\(useConfig.headers)")
            debugPrint("parameter：\(parameter ?? [:])")
            /// 尝试构建完整请求url，以下如果没有参数就不打印了
            var components = URLComponents(string: useConfig.baseUrl + requestUrl)
            if let para: Parameters = parameter {
                components?.queryItems = para.map { key, value in
                    URLQueryItem(name: key, value: "\(value)")
                }
                if let fullURL = components?.url {
                    debugPrint("完整请求：\(fullURL)")
                }
            }
        }
    }
}

extension ZYHttpManager {
    
    /// json转字典
    /// - Parameter json: json description
    /// - Returns: description
    private func jsonToDict(_ json: String) -> [String: Any]? {
        let jsonStr = json
        // Step 1: 移除多余的反斜杠
        var processedJsonString = jsonStr
        
        // 使用正则表达式来移除不必要的反斜杠，确保不会破坏转义字符（例如：\"）
        let regex = try? NSRegularExpression(pattern: "\\\\(?!([\"/bfnrt]|u[0-9a-fA-F]{4}))", options: [])
        processedJsonString = regex?.stringByReplacingMatches(in: processedJsonString, options: [], range: NSRange(location: 0, length: processedJsonString.utf16.count), withTemplate: "") ?? jsonStr
        
        // Step 2: 将处理过的字符串转换为 Data
        guard let data = processedJsonString.data(using: .utf8) else {
            debugPrint("Failed to convert string to data")
            return nil
        }
        
        // Step 3: 尝试解析 JSON 数据
        do {
            if let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]],
               let firstDict = jsonArray.first {
                return firstDict
            } else if let jsonDict = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                return jsonDict
            } else {
                debugPrint("Parsed JSON is neither an array of dictionaries nor a dictionary")
                return nil
            }
        } catch let error {
            debugPrint("Failed to parse JSON: \(error.localizedDescription)")
            return nil
        }
    }
}
